package repositorys

import (
	"errors"
	"github.com/jakecoffman/cron"
	"github.com/zhongshaofa/swan-jobs/internal/models"
	"github.com/zhongshaofa/swan-jobs/internal/plugin"
	"github.com/zhongshaofa/swan-jobs/internal/request"
	"github.com/zhongshaofa/swan-jobs/internal/utils/datetime"
	"gorm.io/gorm"
	"time"
)

type TaskInterface interface {
	Detail(id int) (*models.Task, error)
	Create(task *models.Task) (*models.Task, error)
	Update(task *models.Task) error
	GetList(whereTask *models.Task, pagination request.PaginationRequest) ([]*models.Task, int, error)
	Delete(ids []int) error
	ExecTimeList(id int) ([]string, error)
}

type TaskRepository struct {
}

func (TaskRepository) Detail(id int) (*models.Task, error) {
	m := models.Task{}
	result := plugin.DB.First(&m, id)
	if result.Error != nil {
		return nil, result.Error
	}
	return &m, nil
}

func (receiver TaskRepository) GetList(where *models.Task, pagination request.PaginationRequest) ([]*models.Task, int, error) {
	var list []*models.Task

	db := plugin.DB
	db = receiver.buildQuery(where, db).
		Limit(pagination.Limit).
		Offset((pagination.Page - 1) * pagination.Limit)
	result := db.Find(&list)

	if result.Error != nil {
		return nil, 0, result.Error
	}

	var count int64
	receiver.buildQuery(where, db).Count(&count)

	return list, int(count), nil
}

func (TaskRepository) Create(task *models.Task) (*models.Task, error) {
	result := plugin.DB.Create(&task)
	if result.Error != nil {
		return nil, result.Error
	}
	return task, nil
}

func (TaskRepository) Update(task *models.Task) error {
	result := plugin.DB.Save(&task)
	return result.Error
}

func (TaskRepository) Delete(ids []int) error {
	result := plugin.DB.Delete(&models.Task{}, ids)
	if result.Error != nil {
		return result.Error
	}
	return nil
}


func (receiver TaskRepository) SwitchStatus(ids []int, status int) error {
	result := plugin.DB.Model(&models.Task{}).
		Where("id in (?)", ids).
		Update("status", status)
	if result.Error != nil {
		return result.Error
	}
	return nil
}

func (receiver TaskRepository) ExecTimeList(id int) ([]string, error) {
	detail, err := receiver.Detail(id)
	if err != nil {
		return nil, err
	}
	if detail.Mode != models.ModeCron {
		return nil, errors.New("该类型的任务无法获取调度时间")
	}
	var schedulingTimeList []string
	schedule := cron.Parse(detail.CronFormula)
	startTime := time.Now()

	i := 0
	for i < 10 {
		startTime = schedule.Next(startTime)
		startTimeString := startTime.Format("2006-01-02 15:04:05")
		schedulingTimeList = append(schedulingTimeList, startTimeString)
		i++
	}

	datetime.CurrentTime()

	return schedulingTimeList, nil
}

func (TaskRepository) buildQuery(where *models.Task, db *gorm.DB) *gorm.DB {
	if len(where.Name) > 0 {
		db = db.Where("name like ?", where.Name+"%")
	}
	if len(where.Manager) > 0 {
		db = db.Where("manager like ?", where.Manager+"%")
	}
	if where.ID > 0 {
		db = db.Where("id = ?", where.ID)
	}
	if where.Status > 0 {
		db = db.Where("status = ?", where.Status)
	}
	if where.AppId > 0 {
		db = db.Where("app_id = ?", where.AppId)
	}
	return db
}
